﻿#include "qbaseentity.h"
#include <QVariant>
#include <QtDebug>

QBaseEntity::QBaseEntity(QObject *parent)
    : QObject(parent)
{
    ignoreKeys.append("createTime");
    ignoreKeys.append("updateTime");
}

QBaseEntity::QBaseEntity(const QBaseEntity &other)
{
    primaryKey = other.primaryKey;
    ignoreKeys = other.ignoreKeys;
    tableName = other.tableName;
    copyProperties(other);
}

QBaseEntity &QBaseEntity::operator=(const QBaseEntity &other)
{
    primaryKey = other.primaryKey;
    ignoreKeys = other.ignoreKeys;
    tableName = other.tableName;
    copyProperties(other);
    return *this;
}

void QBaseEntity::copyProperties(const QBaseEntity &other)
{
    const QMetaObject *metaObject = other.metaObject();
    int count = metaObject->propertyCount();
    for (int i = 0; i < count; ++i)
    {
        QMetaProperty property = metaObject->property(i);
        QString propertyName = property.name();
        QVariant value = other.property(propertyName.toLatin1().data());
        setProperty(propertyName.toLatin1().data(), value);
    }
}

QJsonObject QBaseEntity::toJsonObject(QBaseEntity::PropertiesType type, QStringList propertyList) const
{
    QVariantMap properties;
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    case IgnoreOutProperty:
        properties = getIgnoreOutProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }

    QJsonObject jsonObject;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        jsonObject[it.key()] = qvariantToJsonValue(it.value());
    }
    return jsonObject;

    //    const QMetaObject *metaObject = this->metaObject();
    //    for (int i = 0; i < metaObject->propertyCount(); ++i) {
    //        QMetaProperty metaProperty = metaObject->property(i);
    //        if (metaProperty.isReadable()) {
    //            QVariant value = metaProperty.read(this);
    //            if (value.isValid()) {
    //                QString propertyName = metaProperty.name();
    //                // 忽略 objectName 属性
    //                if (propertyName == "objectName") {
    //                    continue;
    //                }
    //                jsonObject[propertyName] = qvariantToJsonValue(value);
    //            }
    //        }
    //    }
    //    return jsonObject;
}

void QBaseEntity::fromJsonObject(const QJsonObject &jsonObject)
{
    const QMetaObject *metaObject = this->metaObject();
    for (const QString &key : jsonObject.keys())
    {
        int index = metaObject->indexOfProperty(key.toLatin1().constData());
        if (index != -1)
        {
            QMetaProperty metaProperty = metaObject->property(index);
            if (metaProperty.isWritable())
            {
                QString propertyName = metaProperty.name();

                /**
                  包含自定义对象例子
                    if (metaProperty.userType() == qMetaTypeId<QList<MyClass*>>()) {
                        QList<MyClass*> list;
                        QJsonArray jsonArray = jsonValue.toArray();
                        for (const QJsonValue &value : jsonArray) {
                            MyClass *child = new MyClass(this);
                            child->fromJson(value.toObject());
                            list.append(child);
                        }
                        metaProperty.write(this, QVariant::fromValue(list));
                    } else {
                        QVariant value = qjsonValueToVariant(jsonValue, metaProperty.type());
                        metaProperty.write(this, value);
                    }

                  */

                if (jsonObject.contains(propertyName))
                {
                    QJsonValue jsonValue = jsonObject[propertyName];
                    if (jsonValue.isNull())
                    {
                        continue;
                    }
                    QVariant value = qjsonValueToVariant(jsonValue, metaProperty.type());
                    metaProperty.write(this, value);
                }
            }
        }
    }
}

bool QBaseEntity::isEmpty()
{
    const QMetaObject *metaObject = this->metaObject();
    int propertyCount = metaObject->propertyCount();

    for (int i = metaObject->propertyOffset(); i < propertyCount; ++i)
    {
        QMetaProperty property = metaObject->property(i);
        const char *propertyName = property.name();
        // 忽略 objectName 属性
        if (QString::fromLatin1(propertyName) == "objectName")
        {
            continue;
        }

        QVariant value = property.read(this);

        if (!isValueEmpty(value))
        {
            //qDebug() << property.name() << "not Empty" << value;
            return false;
        }
    }

    return true;
}

void QBaseEntity::clear()
{
    const QMetaObject *metaObject = this->metaObject();
    int propertyCount = metaObject->propertyCount();
    for (int i = metaObject->propertyOffset(); i < propertyCount; ++i)
    {
        QMetaProperty property = metaObject->property(i);
        this->setProperty(property.name(), QVariant());
    }
}

void QBaseEntity::fromSqlQuery(const QSqlQuery &sql_query)
{
    QVariantMap properties = getAllProperties();
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        QVariant value = qSqlValueToVariant(sql_query.value(it.key()), it->type());
        if (!value.isNull())
        {
            this->setProperty(it.key().toLatin1(), value);
        }
    }
}

void QBaseEntity::setTableName(const QString &value)
{
    tableName = value;
}

QString QBaseEntity::getTableName() const
{
    return tableName;
}

QString QBaseEntity::getPrimaryKey() const
{
    return primaryKey;
}

void QBaseEntity::setPrimaryKey(const QString &value)
{
    primaryKey = value;
}

QJsonValue QBaseEntity::qvariantToJsonValue(const QVariant &value) const
{
    switch (value.type())
    {
    case QVariant::String:
        return QJsonValue(value.toString());
    // case QVariant::StringList:
    //     return QJsonValue(value.toStringList().join(","));
    case QVariant::Int:
        return QJsonValue(value.toInt());
    case QVariant::Double:
        return QJsonValue(value.toDouble());
    case QVariant::Bool:
        return QJsonValue(value.toBool());
    case QVariant::Map:
        return QJsonValue(QJsonObject::fromVariantMap(value.toMap()));
    case QVariant::List:
        return QJsonValue(QJsonArray::fromVariantList(value.toList()));
    case QVariant::Date:
        return QJsonValue(value.toDate().toString("yyyy-MM-dd"));
    case QVariant::Time:
        return QJsonValue(value.toTime().toString("hh:mm:ss"));
    case QVariant::DateTime:
        return QJsonValue(value.toDateTime().toString("yyyy-MM-dd hh:mm:ss"));
    default:
        return QJsonValue::fromVariant(value);
    }
}

QVariant QBaseEntity::qjsonValueToVariant(const QJsonValue &value, int type) const
{
    switch (type)
    {
    case QVariant::String:
        return value.toString();
        //    case QVariant::StringList:
        //        return value.toString().split(",");
    case QVariant::Int:
        return value.toInt();
    case QVariant::Double:
        return value.toDouble();
    case QVariant::Bool:
        return value.toBool();
    case QVariant::Map:
        return value.toObject().toVariantMap();
    case QVariant::List:
        return value.toArray().toVariantList();
    default:
        return value.toVariant();
    }
}

QVariant QBaseEntity::qSqlValueToVariant(const QVariant &value, int type) const
{
    QVariant variant;
    switch (type)
    {
    case QVariant::StringList:
        variant = value.toString().split(",", QString::SkipEmptyParts);
        break;
    default:
        variant = value;
        break;
    }
    return variant;
}

bool QBaseEntity::isValueEmpty(const QVariant &value) const
{
    if (value.isNull())
    {
        return true;
    }

    switch (value.type())
    {
    case QVariant::String:
        return value.toString().isEmpty();
    case QVariant::StringList:
        return value.toStringList().isEmpty();
    case QVariant::Char:
        return value.toChar().isNull();
    case QVariant::Int:
        return value.toInt() == 0;
    case QVariant::UInt:
        return value.toUInt() == 0;
    case QVariant::LongLong:
        return value.toLongLong() == 0;
    case QVariant::ULongLong:
        return value.toULongLong() == 0;
    case QVariant::Double:
        return value.toDouble() == 0.0;
    case QVariant::Bool:
        return !value.toBool();
    case QVariant::List:
        return value.toList().isEmpty();
    case QVariant::Map:
        return value.toMap().isEmpty();
    case QVariant::Hash:
        return value.toHash().isEmpty();
    case QVariant::Date:
        return !value.toDate().isValid();
    case QVariant::Time:
        return !value.toTime().isValid();
    case QVariant::DateTime:
        return !value.toDateTime().isValid();
    default:
        return true; // 默认情况下认为是空
    }
}

QMap<QString, QVariant> QBaseEntity::getDefaultValueMap() const
{
    return defaultValueMap;
}

void QBaseEntity::setDefaultValueMap(const QMap<QString, QVariant> &value)
{
    defaultValueMap = value;
}

void QBaseEntity::setDefaultValue(const QString &key, const QVariant &value)
{
    defaultValueMap[key] = value;
}

void QBaseEntity::clearDefaultValueMap()
{
    defaultValueMap.clear();
}

QDateTime QBaseEntity::getCreateTime() const
{
    return createTime;
}

void QBaseEntity::setCreateTime(const QDateTime &value)
{
    createTime = value;
}

QDateTime QBaseEntity::getUpdateTime() const
{
    return updateTime;
}

void QBaseEntity::setUpdateTime(const QDateTime &value)
{
    updateTime = value;
}

QMap<QString, uint64_t> QBaseEntity::getPropertiesLengthMap() const
{
    return propertiesLengthMap;
}

void QBaseEntity::setPropertiesLengthMap(const QMap<QString, uint64_t> &value)
{
    propertiesLengthMap = value;
}

void QBaseEntity::setPropertiesLength(const QString &key, const uint64_t length)
{
    propertiesLengthMap[key] = length;
}

void QBaseEntity::clearPropertiesLengthMap()
{
    propertiesLengthMap.clear();
}

QVariantMap QBaseEntity::getAllProperties() const
{
    QVariantMap properties;
    const QMetaObject *metaObject = this->metaObject();
    int count = metaObject->propertyCount();
    //    qDebug() << __FUNCTION__ << tableName <<count;
    for (int i = 0; i < count; ++i)
    {
        QMetaProperty prop = metaObject->property(i);
        const char *propertyName = prop.name();
        // 忽略 objectName 属性
        if (QString::fromLatin1(propertyName) == "objectName")
        {
            continue;
        }
        properties[prop.name()] = prop.read(this);
    }
    return properties;
}

QVariantMap QBaseEntity::getUnEmptyProperties() const
{
    QVariantMap properties;
    const QMetaObject *metaObject = this->metaObject();
    int count = metaObject->propertyCount();
    for (int i = 0; i < count; ++i)
    {
        QMetaProperty prop = metaObject->property(i);
        const char *propertyName = prop.name();
        // 忽略 objectName 属性
        if (QString::fromLatin1(propertyName) == "objectName")
        {
            continue;
        }

        QVariant value = prop.read(this);
        if (isValueEmpty(value))
        {
            continue;
        }
        properties[prop.name()] = value;
    }
    return properties;
}

QVariantMap QBaseEntity::getCustomProperties(QStringList keys) const
{
    QVariantMap properties;
    const QMetaObject *metaObject = this->metaObject();
    int count = metaObject->propertyCount();
    for (int i = 0; i < count; ++i)
    {
        QMetaProperty prop = metaObject->property(i);
        const char *propertyName = prop.name();
        // 忽略 objectName 属性
        if (QString::fromLatin1(propertyName) == "objectName")
        {
            continue;
        }

        if (!keys.contains(propertyName))
        {
            continue;
        }

        QVariant value = prop.read(this);
        properties[prop.name()] = value;
    }
    return properties;
}

QVariantMap QBaseEntity::getIgnoreOutProperties(QStringList keys) const
{
    QVariantMap properties;
    const QMetaObject *metaObject = this->metaObject();
    int count = metaObject->propertyCount();
    for (int i = 0; i < count; ++i)
    {
        QMetaProperty prop = metaObject->property(i);
        const char *propertyName = prop.name();
        // 忽略 objectName 属性
        if (QString::fromLatin1(propertyName) == "objectName")
        {
            continue;
        }

        if (keys.contains(propertyName))
        {
            continue;
        }

        properties[prop.name()] = prop.read(this);
    }
    return properties;
}

QStringList QBaseEntity::getNotNullKeys() const
{
    return notNullKeys;
}

void QBaseEntity::setNotNullKeys(const QStringList &value)
{
    notNullKeys = value;
}

QStringList QBaseEntity::getUniqueKeys() const
{
    return uniqueKeys;
}

void QBaseEntity::setUniqueKeys(const QStringList &value)
{
    uniqueKeys = value;
}

QStringList QBaseEntity::getIgnoreKeys() const
{
    return ignoreKeys;
}

void QBaseEntity::setIgnoreKeys(const QStringList &value)
{
    ignoreKeys = value;
}

QString QBaseEntity::generateSelectSql(QBaseEntity::PropertiesType type, QStringList propertyList) const
{
    QVariantMap properties;
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }
    QStringList whereList;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (ignoreKeys.contains(it.key()))
            continue;
        if (it.value().type() == QVariant::String)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toString()));
        }
        else if (it.value().type() == QVariant::StringList)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toStringList().join(",")));
        }
        else
        {
            whereList.append(QString("`%1` = %2").arg(it.key()).arg(it.value().toString()));
        }
    }
    return QString("SELECT * FROM %1 %2%3")
        .arg(tableName)
        .arg(whereList.size() > 0 ? "WHERE " : "")
        .arg(whereList.join(" and "));
}

QString QBaseEntity::generateSelectCountSql(QBaseEntity::PropertiesType type, QStringList propertyList) const
{
    QVariantMap properties;
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }
    QStringList whereList;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (ignoreKeys.contains(it.key()))
            continue;
        if (it.value().type() == QVariant::String)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toString()));
        }
        else if (it.value().type() == QVariant::StringList)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toStringList().join(",")));
        }
        else
        {
            whereList.append(QString("`%1` = %2").arg(it.key()).arg(it.value().toString()));
        }
    }
    return QString("SELECT COUNT(*) FROM %1 %2%3")
        .arg(tableName)
        .arg(whereList.size() > 0 ? "WHERE " : "")
        .arg(whereList.join(" and "));
}

QString QBaseEntity::generateInsertSql(QBaseEntity::PropertiesType type, QStringList propertyList) const
{
    QVariantMap properties;
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }
    QStringList columns;
    QStringList values;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (primaryKey == it.key() && it.value() == 0)
            continue;
        if (ignoreKeys.contains(it.key()))
            continue;
        //时间类型，为空不生成sql
        if ((it.value().type() == QVariant::DateTime || it.value().type() == QVariant::Date || it.value().type() == QVariant::Time) && !it.value().toDateTime().isValid())
            continue;
        columns.append(QString("`%1`").arg(it.key()));
        if (it.value().type() == QVariant::String)
        {
            values.append(QString("'%1'").arg(it.value().toString()));
        }
        else if (it.value().type() == QVariant::StringList)
        {
            values.append(QString("'%1'").arg(it.value().toStringList().join(",")));
        }
        else if (it.value().type() == QVariant::DateTime)
        {
            values.append(QString("'%1'").arg(it.value().toDateTime().toString("yyyy-MM-dd hh:mm:ss")));
        }
        else
        {
            values.append(QString("%1").arg(it.value().toString()));
        }
    }
    return QString("INSERT INTO %1 (%2) VALUES (%3)")
        .arg(tableName)
        .arg(columns.join(", "))
        .arg(values.join(", "));
}

QString QBaseEntity::generateUpdateSql(QBaseEntity::PropertiesType type, QStringList propertyList, QBaseEntity::PropertiesType onType, QStringList onPropertyList) const
{
    if ((onType == AllProperty) || (onType == UnEmptyProperty))
    {
        qCritical() << "参考属性不可为全属性，或非空属性";
        return "";
    }

    if (onType == PrimaryKeyProperty)
    {
        onPropertyList.clear();
        onPropertyList.append(primaryKey);
    }
    //此处注释掉，因为自定义属性，不从对象内部取值，只生成sql外面来追加
    //    if((onType == CustomProperty) && (onPropertyList.isEmpty())){
    //        qCritical() << "参考属性为自定义属性，但参考属性列表为空";
    //        return "";
    //    }

    QVariantMap properties;
    QVariantMap allProperties = getAllProperties();
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }
    QStringList updates;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (ignoreKeys.contains(it.key()))
            continue;
        if (it.key() == primaryKey)
            continue;
        //时间类型，为空不生成sql
        if ((it.value().type() == QVariant::DateTime || it.value().type() == QVariant::Date || it.value().type() == QVariant::Time) && !it.value().toDateTime().isValid())
            continue;
        //if((onType == CustomProperty) && onPropertyList.contains(it.key())) continue;

        if (it.value().type() == QVariant::String)
        {
            updates.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toString()));
        }
        else if (it.value().type() == QVariant::StringList)
        {
            updates.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toStringList().join(",")));
        }
        else if (it.value().type() == QVariant::DateTime)
        {
            updates.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toDateTime().toString("yyyy-MM-dd hh:mm:ss")));
        }
        else
        {
            updates.append(QString("`%1` = %2").arg(it.key()).arg(it.value().toString()));
        }
    }

    QStringList whereList;
    for (auto it = allProperties.begin(); it != allProperties.end(); ++it)
    {
        if (ignoreKeys.contains(it.key()))
            continue;
        if (!onPropertyList.contains(it.key()))
            continue;
        if (it.value().type() == QVariant::String)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toString()));
        }
        else if (it.value().type() == QVariant::StringList)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toStringList().join(",")));
        }
        else
        {
            whereList.append(QString("`%1` = %2").arg(it.key()).arg(it.value().toString()));
        }
    }

    return QString("UPDATE %1 SET %2 %3%4")
        .arg(tableName)
        .arg(updates.join(", "))
        .arg(whereList.size() > 0 ? "WHERE " : "")
        .arg(whereList.join(" and "));
}

QString QBaseEntity::generateDeleteSql(QBaseEntity::PropertiesType type, QStringList propertyList) const
{
    QVariantMap properties;
    switch (type)
    {
    case UnEmptyProperty:
        properties = getUnEmptyProperties();
        break;
    case CustomProperty:
        properties = getCustomProperties(propertyList);
        break;
    default:
        properties = getAllProperties();
        break;
    }
    if (properties.isEmpty())
    {
        return "";
    }
    QStringList whereList;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (it.value().type() == QVariant::String)
        {
            whereList.append(QString("`%1` = '%2'").arg(it.key()).arg(it.value().toString()));
        }
        else
        {
            whereList.append(QString("`%1` = %2").arg(it.key()).arg(it.value().toString()));
        }
    }
    return QString("DELETE FROM %1 WHERE %2")
        .arg(tableName)
        .arg(whereList.join(" and "));
}

QString QBaseEntity::generateDeleteByKeysSql(QString keyName, QList<QString> values) const
{
    if (values.size() == 0)
    {
        qCritical() << __FUNCTION__ << QString("参数集合不可为空");
        return "";
    }
    QStringList valueList;
    QVariantMap properties = getAllProperties();
    bool isString = false;
    bool isFind = false;
    for (auto it = properties.begin(); it != properties.end(); ++it)
    {
        if (it.key() == keyName)
        {
            isFind = true;
            if (it.value().type() == QVariant::String)
            {
                isString = true;
            }
        }
    }
    if (!isFind || values.size() == 0)
    {
        qCritical() << QString("属性:%1 不存在").arg(keyName);
        return "";
    }
    for (QString &val : values)
    {
        valueList.append(QString(isString ? "'%1'" : "%1").arg(val));
    }

    return QString("DELETE FROM %1 WHERE %2 in [%3]")
        .arg(tableName)
        .arg(keyName)
        .arg(valueList.join(","));
}

QString QBaseEntity::generateCreateTableSql(const QString &driverName) const
{
    QVariantMap properties = getAllProperties();
    //qDebug()<< __FUNCTION__ << properties.size();
    QMetaObject const *metaObject = this->metaObject();
    int count = metaObject->propertyCount();
    QStringList columns;
    QString IncrementKey; //自增触发
    QString createTimeScript;
    QString updateTimeScript;
    QMap<QVariant::Type, QString> typeMapping;

    if (driverName == "QMYSQL")
    {
        IncrementKey = "AUTO_INCREMENT PRIMARY KEY ";
        createTimeScript = "DEFAULT CURRENT_TIMESTAMP ";
        updateTimeScript = "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
        typeMapping = {
            {QVariant::Int, "INT"},
            {QVariant::LongLong, "BIGINT"},
            {QVariant::ULongLong, "BIGINT UNSIGNED"},
            {QVariant::String, "VARCHAR(255)"},
            {QVariant::StringList, "VARCHAR(255)"},
            {QVariant::Date, "DATE"},
            {QVariant::Time, "TIME"},
            {QVariant::DateTime, "DATETIME"},
            {QVariant::Bool, "TINYINT(1)"},
            {QVariant::Double, "DOUBLE"},
            {QVariant::ByteArray, "BLOB"}};
    }
    else
    { //SQLite
        IncrementKey = "PRIMARY KEY AUTOINCREMENT ";
        createTimeScript = "DATETIME DEFAULT CURRENT_TIMESTAMP ";
        updateTimeScript = "DATETIME DEFAULT CURRENT_TIMESTAMP ";
        typeMapping = {
            {QVariant::Int, "INTEGER"},
            {QVariant::LongLong, "INTEGER"},
            {QVariant::ULongLong, "INTEGER"},
            {QVariant::String, "TEXT"},
            {QVariant::StringList, "TEXT"},
            {QVariant::Date, "DATE"},
            {QVariant::Time, "TIME"},
            {QVariant::DateTime, "DATETIME"},
            {QVariant::Bool, "INTEGER"},
            {QVariant::Double, "REAL"},
            {QVariant::ByteArray, "BLOB"}};
    }

    //    for (int i = metaObject->propertyOffset(); i < count; ++i) {
    for (int i = 1; i < count; ++i)
    {
        QMetaProperty prop = metaObject->property(i);
        QString columnName = prop.name();
        QString columnType = typeMapping.value(static_cast<QVariant::Type>(prop.type()), "TEXT");
        //指定长度的判断是否使用
        if (propertiesLengthMap.contains(columnName) && driverName == "QMYSQL")
        {
            uint64_t propertiesLength = propertiesLengthMap[columnName];
            if (propertiesLength <= 255)
            {
                columnType = "VARCHAR(255)";
            }
            else if (propertiesLength <= 65536)
            {
                columnType = "TEXT";
            }
            else if (propertiesLength <= 16777215)
            {
                columnType = "MEDIUMTEXT";
            }
            else if (propertiesLength <= 4294967295)
            {
                columnType = "LONGTEXT";
            }
            else
            {
                columnType = "LONGTEXT";
                qCritical() << __FUNCTION__ << "数据长度过大！";
            }
        }
        QString columnDefaultValue = "";
        switch (prop.type())
        {
        case QVariant::Int:
        case QVariant::LongLong:
        case QVariant::ULongLong:
        case QVariant::Bool:
        case QVariant::Double:
            columnDefaultValue = defaultValueMap.value(columnName).toString();
            break;
        case QVariant::String:
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toString());
            break;
        case QVariant::StringList:
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toStringList().join(","));
            break;
        case QVariant::Date:
            columnType = "DATE";
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toDate().toString("YYYY-MM-DD"));
            break;
        case QVariant::Time:
            columnType = "TIME";
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toTime().toString("hh:mm:ss"));
            break;
        case QVariant::DateTime:
            columnType = "DATETIME";
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toDateTime().toString("YYYY-MM-DD hh:mm:ss"));
            break;
        default:
            columnDefaultValue = QString("'%1'").arg(defaultValueMap.value(columnName).toString());
            break;
        }
        if (columnName == "createTime")
        {
            columns.append(QString("`%1` %2 %3")
                               .arg(columnName)
                               .arg(columnType)
                               .arg(createTimeScript));
            continue;
        }
        if (columnName == "updateTime")
        {
            columns.append(QString("`%1` %2 %3")
                               .arg(columnName)
                               .arg(columnType)
                               .arg(updateTimeScript));
            continue;
        }
        columns.append(QString("`%1` %2 %3%4%5%6")
                           .arg(columnName)
                           .arg(columnType)
                           .arg(columnName == primaryKey ? IncrementKey : "")
                           .arg(uniqueKeys.contains(columnName) ? "UNIQUE " : "")
                           .arg(notNullKeys.contains(columnName) ? "NOT NULL " : "")
                           .arg(defaultValueMap.contains(columnName) ? QString("DEFAULT %1 ").arg(columnDefaultValue) : ""));
    }

    //    QString cretateFlipflop = QString("CREATE TRIGGER update_%1_update_time "
    //                                      "AFTER UPDATE ON `%1` "
    //                                      "FOR EACH ROW "
    //                                      "BEGIN "
    //                                          "UPDATE `%1` SET `updateTime` = CURRENT_TIMESTAMP WHERE `id` = OLD.id; "
    //                                      "END;").arg(tableName);

    return QString("CREATE TABLE IF NOT EXISTS `%1` (%2)").arg(tableName).arg(columns.join(", "));
}
